package com.xuecheng.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.base.model.PageParams;
import com.xuecheng.base.model.PageResult;
import com.xuecheng.content.checkutils.CheckInsertResultUtil;
import com.xuecheng.content.config.QueryWrapperBuilder;
import com.xuecheng.content.conver.CourseBaseConverter;
import com.xuecheng.content.mapper.*;
import com.xuecheng.content.model.dto.*;
import com.xuecheng.content.model.po.*;
import com.xuecheng.content.service.CourseBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Autowired
    private CourseBaseMapper courseBaseMapper;

    @Autowired
    private CourseDeptMapper courseDeptMapper;

    @Autowired
    private CourseTeacherMapper courseTeacherMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private TeachplanMapper teachplanMapper;
    @Autowired
    private TeachplanMediaMapper teachplanMediaMapper;

    private static final Pattern MD5_PATTERN = Pattern.compile("/([a-f0-9]{32})\\.[a-z]+$", Pattern.CASE_INSENSITIVE);

    @Override
    public PageResult<CourseBaseInfoDto> list(PageParams pageParams, QueryCourseParamsDto queryCourseParamsDto) {
        LambdaQueryWrapper<CourseBase> queryWrapper = new LambdaQueryWrapper<>();
        new QueryWrapperBuilder<CourseBase, QueryCourseParamsDto>(queryWrapper, queryCourseParamsDto)
                .addLikeCondition(queryCourseParamsDto::getCourseName, CourseBase::getName)
                .addEqCondition(queryCourseParamsDto::getAuditStatus, CourseBase::getAuditStatus)
                .addEqCondition(queryCourseParamsDto::getPublishStatus, CourseBase::getStatus)
                .addEqCondition(queryCourseParamsDto::getCompanyId,CourseBase::getCompanyId);

        Page<CourseBase> courseBasePage = courseBaseMapper.selectPage(new Page<>(pageParams.getPageNo(), pageParams.getPageSize()), queryWrapper);
        List<CourseBaseInfoDto> courseBaseInfoDtoList = new ArrayList<>();
        courseBasePage.getRecords().forEach(courseBase -> {
            CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
            // 安全查询并拷贝属性到DTO
            Optional.ofNullable(courseMarketMapper.selectById(courseBase.getId())).ifPresent(market -> {BeanUtils.copyProperties(market, courseBaseInfoDto);});
            BeanUtils.copyProperties(courseBase,courseBaseInfoDto);
            List<Teachplan> teachplanList = teachplanMapper.selectList(new LambdaQueryWrapper<Teachplan>().eq(Teachplan::getCourseId, courseBase.getId()).ne(Teachplan::getGrade, '1'));
            courseBaseInfoDto.setSubsectionNum(teachplanList.size());  //获取任务数量
            courseBaseInfoDtoList.add(courseBaseInfoDto);
        });

        return new PageResult<>(courseBaseInfoDtoList ,pageParams.getPageNo(), pageParams.getPageSize(),courseBasePage.getTotal());
    }

    //    创建课程计划
    @Override
    @Transactional
    public CourseBaseInfoDto createCourseBase(Long companyId, CourseTeacherDto courseTeacher, AddCourseDto addCourseDto) {
//          新增课程基本信息
        CourseBaseConverter courseBaseConverter = new CourseBaseConverter();
        CourseBase courseBaseInsert = courseBaseConverter.AddCourseDtoConverToCourseBase(addCourseDto, courseTeacher);
        courseBaseInsert.setCompanyId(companyId);
//        查询部门
        CourseDept dept = CheckInsertResultUtil.checkExist(courseDeptMapper.selectById(companyId),() -> new XueChengPlusException("机构不存在"));
        courseBaseInsert.setCompanyName(dept.getDeptName());
        CheckInsertResultUtil.check(courseBaseMapper.insert(courseBaseInsert), () -> new XueChengPlusException("课程基本信息新增失败"));
//        新增教师信息 一个教师对应多个课程
        CourseTeacher courseTeacherInsert = courseBaseConverter.courseTeacherConverToCourseTeacherInsert(courseTeacher);
        courseTeacherInsert.setCourseId(courseBaseInsert.getId());
        CheckInsertResultUtil.check(courseTeacherMapper.insert(courseTeacherInsert),() -> new XueChengPlusException("教师信息新增失败"));
//          新增课程营销信息
        CourseMarket courseMarketInsert = new CourseMarket();
        BeanUtils.copyProperties(addCourseDto,courseMarketInsert);
        CheckInsertResultUtil.check(courseMarketMapper.insert(courseMarketInsert),() -> new XueChengPlusException("课程营销信息新增失败"));
//        拼装返回
        return courseBaseConverter.courseBaseAndCourseMarketCoverToCourseBaseInfoDto(courseMarketInsert, courseBaseInsert);
    }

//    更新课程信息
    @Override
    public CourseBaseInfoDto updateCourseDase(Long companyId, EditCourseDto editCourseDto) {
//        校验
//        业务逻辑代码
//        要更新课程基本信息和课程营销信息
        CourseBase courseBaseSelect = courseBaseMapper.selectById(editCourseDto.getId());
        CourseMarket courseMarketSelect = courseMarketMapper.selectById(editCourseDto.getId());
        BeanUtils.copyProperties(editCourseDto,courseBaseSelect);
        BeanUtils.copyProperties(editCourseDto,courseMarketSelect);
        CheckInsertResultUtil.check(courseBaseMapper.updateById(courseBaseSelect),()->new XueChengPlusException("课程基本信息更新失败"));
        CheckInsertResultUtil.check(courseMarketMapper.updateById(courseMarketSelect),()->new XueChengPlusException("课程营销信息更新失败"));

        CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
        BeanUtils.copyProperties(courseMarketSelect,courseBaseInfoDto);
        BeanUtils.copyProperties(courseBaseSelect,courseBaseInfoDto);

        return courseBaseInfoDto;
    }

//    依据id查取信息
    @Override
    public CourseBaseInfoDto selectCourseBaseAndMarketById(Long courseId) {
        CourseBase courseBaseSelect = courseBaseMapper.selectById(courseId);
        CourseMarket courseMarketSelect = courseMarketMapper.selectById(courseId);
        CourseBaseInfoDto courseBaseInfoDto = new CourseBaseInfoDto();
        BeanUtils.copyProperties(courseMarketSelect,courseBaseInfoDto);
        BeanUtils.copyProperties(courseBaseSelect,courseBaseInfoDto);

        return courseBaseInfoDto;
    }

//    删除对应信息
    @Override
    @Transactional
    public void deleteCourseBase(Long courseId) {

//        删除课程信息
        int courseBaseResult = courseBaseMapper.deleteById(courseId);
//        课程营销信息
        int courseMarketResult = courseMarketMapper.deleteById(courseId);
//        删除教师信息
        int courseTeacherResult = courseTeacherMapper.delete(new LambdaQueryWrapper<CourseTeacher>().eq(CourseTeacher::getCourseId, courseId));
//        删除课程大纲树
        int teachplanResult = teachplanMapper.delete(new LambdaQueryWrapper<Teachplan>().eq(Teachplan::getCourseId, courseId));
        int teachplanMediaResult = teachplanMediaMapper.delete(new LambdaQueryWrapper<TeachplanMedia>().eq(TeachplanMedia::getCourseId, courseId));
    }


    //课程基本信息更新图片
    @Override
    public Boolean updateCoursePic(Long courseId, String picUrl) {

        boolean flag = true;
        CourseBase courseBaseInsert = new CourseBase();
        courseBaseInsert.setPic(picUrl);
        courseBaseInsert.setId(courseId);
        int i = courseBaseMapper.updateNotEmpty(courseBaseInsert);
        if(i<=0){
            flag=false;
        }
        return flag;
    }

//    查询图片地址提取 md5 值
    @Override
    public Map<String, String> courseIdExtractMd5(String courseId) {
        Map<String, String> deleteImageMap = new HashMap<>();
        CourseBase selectCourseBase = courseBaseMapper.selectById(courseId);
        String picUrl = selectCourseBase.getPic();
        String md5 = Optional.ofNullable(picUrl)
                .flatMap(this::extractMd5)
                .orElseGet(() -> {
                    log.warn("无法从URL提取MD5: {}", picUrl);
                    return "invalid-md5";
                });
        deleteImageMap.put("md5",md5);
        deleteImageMap.put("url",picUrl);
        return deleteImageMap;
    }

    @Override
    public CourseBase selectById(Long courseId) {
        return courseBaseMapper.selectById(courseId);
    }

    //    url 提取 md5
    public Optional<String> extractMd5(String url) {
        return Optional.ofNullable(url)
                .map(java.net.URI::create)
                .map(java.net.URI::getPath)
                .map(path -> {
                    Matcher matcher = MD5_PATTERN.matcher(path.toLowerCase());
                    return matcher.find() ? matcher.group(1) : null;
                });
    }

}
















